(function() {
    Nokia.LightBox = Nokia.Widget.extend({
        initialize: function(options) {
            var instance = this;

			var defaults = {
				autoOpen: false,
				overflow: true,
				height: 28,
				applyRoundedCorners: true,
				width: 28
            };

            instance.options = jQuery.extend(defaults, options);

            instance.element = jQuery( instance.options.element );

            instance._super.apply(instance, [instance.options]);

            instance.registerData("lightbox");

            instance._create();
            instance._attatchEvents();

			instance.registerVibrationOn(['show']);
			instance.fireCallback('create');
        },

		destroy: function() {
			var instance = this;

			Nokia.dom.remove(instance.overflow);
			Nokia.dom.remove(instance.box);

			instance.fireCallback('destroy');
		},

		_hide: function(element) {
			Nokia.dom.domEl(element).style.display = 'none';
		},

		_show: function(element) {
			Nokia.dom.domEl(element).style.display = 'block';
		},

		close: function() {
			var instance = this;
			var options = instance.options;

			instance._hide(instance.overflow);

			if (options.animation) {
				Nokia.animation.fadeOut(instance.box);
			} else {
				instance._hide(instance.box);
			}

			instance.fireCallback('hide');
		},

		open: function() {
			var instance = this;
			var options = instance.options;

			instance._show(instance.element);

			instance._show(instance.overflow);

			if (options.animation) {
				Nokia.animation.fadeIn(instance.box);
			} else {
				instance._show(instance.box);
			}

			instance._updatePosition();

			instance.fireCallback('show');
		},

		_attatchEvents: function() {
			var instance = this;
			var Styles = instance.Styles;

			window.addEventListener('resize',function() {
				if (instance.box.is(':visible')) {
					instance._updatePosition();
				}
			}, false);

			instance.box.find('.' + Styles.lightboxButton).hover(function() {
				Nokia.util.removeClass(this, Styles.uiStateDefault);
				Nokia.util.addClass(this, Styles.uiStateHover);
			}, function() {
				Nokia.util.removeClass(this, Styles.uiStateHover);
				Nokia.util.addClass(this, Styles.uiStateDefault);
			});

		},

		_create: function() {
			var instance = this;
			var options = instance.options;
			var element = instance.element;
			var Styles = instance.Styles;
			var isBody = element[0] == document.body;

			Nokia.util.addClass(element[0], Styles.lightbox);

			instance.elementHeight = isBody ? window.innerHeight : element.outerHeight();
			instance.elementWidth = isBody ? window.innerWidth : element.outerWidth();

			instance._createOverflow(element);
			instance._createBox(element);
			instance._createButtons();

			instance._hide(instance.element);

			if ( options.autoOpen ) {
				instance.open();
			}
		},

		_createButtons: function() {
			var instance = this;
			var options = instance.options;
			var element = instance.element;
			var Styles = instance.Styles;
			var buttons = options.buttons;

			var buttonsWrapper = Nokia.dom.parseHTML('<div class="' + [Styles.lightboxButtonsContainer].join(' ') + '"></div>');
			Nokia.dom.append(element, buttonsWrapper);

			var closeWrapper = Nokia.dom.parseHTML('<div class="' + [Styles.lightboxButtonCloseContainer].join(' ') + '"></div>');
			Nokia.dom.append(element, closeWrapper);

			instance.buttonsWrapper = buttonsWrapper;
			instance.closeWrapper = closeWrapper;

			for (var label in buttons) {

				(function() {

					var buttonElement = Nokia.dom.parseHTML(
						'<span href="javascript:void(0);" class="' + [
							Styles.lightboxButton,
							Styles.uiStateDefault,
							Styles.uiPriorityPrimary,
							Styles.uiWidgetHeader
						].join(' ') + '">' + label + '</span>'
					);

					Nokia.dom.append(buttonsWrapper, buttonElement);

					var action = buttons[label];

					var actionCall = function(e) {
						action.apply(instance, [e]);
					};

					(new Nokia.Button({
						element: buttonElement,
						click: actionCall,
						label: label
					}));

				})();

			}

			if (options.buttonClose) {
				var buttonClose = Nokia.dom.parseHTML(
					'<span href="javascript:void(0);" class="' + [
						Styles.lightboxButton,
						Styles.lightboxButtonClose,
						Styles.uiStateDefault
					].join(' ') + '">x</span>'
				);

				var closeAction = function(e) {
					instance.close();
				};

				Nokia.dom.append(closeWrapper, buttonClose);

				(new Nokia.Button({
					element: buttonClose,
					click: closeAction,
					label: 'x'
				}));
			}

		},

		_createBox: function() {
			var instance = this;
			var options = instance.options;
			var Styles = instance.Styles;
			var element = instance.element;

			var box = Nokia.dom.parseHTML('<div class="' + Styles.lightboxBox +'"></div>');
			Nokia.dom.append('body', box);

			var elementWrapper = Nokia.dom.parseHTML('<div class="' + [Styles.uiWidgetHeader, Styles.uiStateDefault].join(' ') + '"></div>');
			Nokia.dom.append(box, elementWrapper);
			Nokia.dom.append(elementWrapper, element);

			if (options.applyRoundedCorners) {
				Nokia.util.applyRoundedCorners(elementWrapper, null, null, false);
			}

			instance.box = box;
		},

		updatePosition: function() {
			var instance = this;

			instance._updatePosition(true);
		},

		_updatePosition: function(force) {
			var instance = this;
			var options = instance.options;
			var element = instance.element;
			var box = instance.box;
			var Styles = instance.Styles;
			var overflow = instance.overflow;

			// Best performmance
			if (!instance._windowChanged() && !force) {
				return;
			}

			// Position box
			var height = options.height || element.outerHeight();
			var width = options.width || element.outerWidth();

			if (width.indexOf('%') > -1) {
				width = (width.replace(/%/, '') / 100) * window.innerWidth;
			}
			if (height.indexOf('%') > -1) {
				height = (height.replace(/%/, '') / 100) * window.innerHeight;
			}

			// Calculate buttons width
			var buttons = instance.buttonsWrapper.find('.' + Styles.nokiaButton);
			var outer = parseInt(buttons.css('margin-left'), 10) + parseInt(buttons.css('margin-right'), 10) + parseInt(buttons.css('padding-left'), 10) + parseInt(buttons.css('padding-right'), 10) + parseInt(buttons.css('border-left-width'), 10) + parseInt(buttons.css('border-right-width'), 10);
			var buttonWidth = ((width - (outer + 2) * buttons.length) / buttons.length);

			buttons.width(buttonWidth);

			element.css({
				height: height,
				width: width
			});

			var scrollTop = jQuery(window).scrollTop();

			box.css({
				top: window.innerHeight / 2 - element.outerHeight() / 2 + scrollTop,
				left: window.innerWidth / 2 - element.outerWidth() / 2,
				width: width,
				height: height
			});

			instance._updateWindowState();
		},

		_windowChanged: function() {
			var instance = this;

			return (instance.lastWidth != window.innerWidth || instance.lastHeight != window.innerHeight);
		},

		_updateWindowState: function() {
			var instance = this;

			instance.lastWidth = window.innerWidth;
			instance.lastHeight = window.innerHeight;
		},

		_createOverflow: function(element) {
			var instance = this;

			var overflow = Nokia.util.createOverflow();

			instance.overflow = overflow;
		},

		Styles: {
			nokiaButton: 'nokia-button',
			lightbox: 'nokia-lightbox-element',
			lightboxButton: 'nokia-lightbox-button',
			lightboxButtonClose: 'nokia-lightbox-button-close',
			lightboxButtonsContainer: 'nokia-lightbox-button-container',
			lightboxButtonCloseContainer: 'nokia-lightbox-button-close-container',
			lightboxBox: 'nokia-lightbox',
			nokiaOverflow: 'nokia-overflow',
			uiStateDefault: 'ui-state-default',
			uiStateActive: 'ui-state-active',
			uiStateHover: 'ui-state-hover',
			uiStateHighLight: 'ui-state-highlight',
			uiWidgetHeader: 'ui-widget-header',
			uiPriorityPrimary: 'ui-priority-primary'
		}
    });
})();